home *** CD-ROM | disk | FTP | other *** search
/ STraTOS 1997 April & May / STraTOS 1 - 1997 April & May.iso / CD01 / INTERNET / SITES / LITTLE / P3SRC.ZIP / ATARI / WARPS.C < prev    next >
Encoding:
C/C++ Source or Header  |  1996-02-07  |  12.0 KB  |  444 lines

  1. /**************************************************************************
  2. *                warps.c
  3. *
  4. *  This module implements functions that warp or modify the point at which
  5. *  a texture pattern is evaluated.
  6. *
  7. *  from Persistence of Vision(tm) Ray Tracer
  8. *  Copyright 1996 Persistence of Vision Team
  9. *---------------------------------------------------------------------------
  10. *  NOTICE: This source code file is provided so that users may experiment
  11. *  with enhancements to POV-Ray and to port the software to platforms other
  12. *  than those supported by the POV-Ray Team.  There are strict rules under
  13. *  which you are permitted to use this file.  The rules are in the file
  14. *  named POVLEGAL.DOC which should be distributed with this file. If
  15. *  POVLEGAL.DOC is not available or for more info please contact the POV-Ray
  16. *  Team Coordinator by leaving a message in CompuServe's Graphics Developer's
  17. *  Forum.  The latest version of POV-Ray may be found there as well.
  18. *
  19. * This program is based on the popular DKB raytracer version 2.12.
  20. * DKBTrace was originally written by David K. Buck.
  21. * DKBTrace Ver 2.0-2.12 were written by David K. Buck & Aaron A. Collins.
  22. *
  23. *****************************************************************************/
  24.  
  25. #include "frame.h"
  26. #include "vector.h"
  27. #include "povproto.h"
  28. #include "matrices.h"
  29. #include "warps.h"
  30. #include "pattern.h"
  31. #include "texture.h"
  32.  
  33. /*****************************************************************************
  34. * Local preprocessor defines
  35. ******************************************************************************/
  36.  
  37. #define COORDINATE_LIMIT 1.0e17
  38.  
  39.  
  40. /*****************************************************************************
  41. * Static functions
  42. ******************************************************************************/
  43.  
  44.  
  45.  
  46. /*****************************************************************************
  47. *
  48. * FUNCTION
  49. *
  50. *   Warp_EPoint
  51. *
  52. * INPUT
  53. *
  54. *   EPoint -- The original point in 3d space at which a pattern
  55. *   is evaluated.
  56. *   TPat   -- Texture pattern struct
  57. *   
  58. * OUTPUT
  59. *
  60. *   TPoint -- Point after turbulence and transform
  61. *   have been applied
  62. *   
  63. * RETURNS
  64. *   
  65. * AUTHOR
  66. *
  67. *   POV-Ray Team
  68. *   
  69. * DESCRIPTION
  70. *
  71. * CHANGES
  72. *
  73. ******************************************************************************/
  74.  
  75. void Warp_EPoint (TPoint, EPoint, TPat)
  76. VECTOR TPoint;
  77. VECTOR EPoint;
  78. TPATTERN *TPat;
  79. {
  80.    VECTOR PTurbulence,RP;
  81.    int Axis,i;
  82.    int blockX = 0, blockY = 0, blockZ = 0 ;
  83.    SNGL BlkNum;
  84.    DBL  Length;
  85.    DBL  Strength;
  86.    WARP *Warp=TPat->Warps;
  87.    TURB *Turb;
  88.    TRANS *Tr;
  89.    REPEAT *Repeat;
  90.    BLACK_HOLE *Black_Hole;
  91.    VECTOR Delta, Center;
  92.  
  93.    Assign_Vector(TPoint, EPoint);
  94.  
  95.    while (Warp != NULL)
  96.    {
  97.       switch(Warp->Warp_Type)
  98.       {
  99.         case CLASSIC_TURB_WARP:
  100.           if ((TPat->Type == MARBLE_PATTERN) ||
  101.               (TPat->Type == NO_PATTERN)     ||
  102.               (TPat->Type == WOOD_PATTERN))
  103.           {
  104.              break;
  105.           }
  106.         /* If not a special type, fall through to next case */
  107.  
  108.         case EXTRA_TURB_WARP:
  109.           Turb=(TURB *)Warp;
  110.           DTurbulence (PTurbulence, TPoint, Turb);
  111.           TPoint[X] += PTurbulence[X] * Turb->Turbulence[X];
  112.           TPoint[Y] += PTurbulence[Y] * Turb->Turbulence[Y];
  113.           TPoint[Z] += PTurbulence[Z] * Turb->Turbulence[Z];
  114.           break;
  115.  
  116.         case NO_WARP:
  117.           break;
  118.  
  119.         case TRANSFORM_WARP:
  120.           Tr=(TRANS *)Warp;
  121.           MInvTransPoint(TPoint, TPoint, &(Tr->Trans));
  122.           break;
  123.  
  124.         case REPEAT_WARP:
  125.           Repeat=(REPEAT *)Warp;
  126.           Assign_Vector(RP,TPoint);
  127.           Axis=Repeat->Axis;
  128.           BlkNum=floor(TPoint[Axis]/Repeat->Width);
  129.           if (((int)BlkNum) & 1)
  130.           {          
  131.              VEvaluateEq(RP,Repeat->Flip);
  132.           }
  133.           VAddScaledEq(RP,BlkNum,Repeat->Offset);
  134.           RP[Axis]=TPoint[Axis]-BlkNum*Repeat->Width;
  135.           Assign_Vector(TPoint,RP);
  136.           break;
  137.  
  138.         case BLACK_HOLE_WARP:
  139.           Black_Hole = (BLACK_HOLE *) Warp ;
  140.           Assign_Vector (Center, Black_Hole->Center) ;
  141.  
  142.           if (Black_Hole->Repeat)
  143.           {
  144.             /* first, get the block number we're in for each dimension  */
  145.             /* block numbers are (currently) calculated relative to 0   */
  146.             /* we use floor () since it correctly returns -1 for the
  147.                first block below 0 in each axis                         */
  148.             /* one final point - we could run into overflow problems if
  149.                the repeat vector was small and the scene very large.    */
  150.             if (Black_Hole->Repeat_Vector [X] >= Small_Tolerance)
  151.               blockX = (int) floor (TPoint [X] / Black_Hole->Repeat_Vector [X]) ;
  152.  
  153.             if (Black_Hole->Repeat_Vector [Y] >= Small_Tolerance)
  154.               blockY = (int) floor (TPoint [Y] / Black_Hole->Repeat_Vector [Y]) ;
  155.  
  156.             if (Black_Hole->Repeat_Vector [Z] >= Small_Tolerance)
  157.               blockZ = (int) floor (TPoint [Z] / Black_Hole->Repeat_Vector [Z]) ;
  158.  
  159.             if (Black_Hole->Uncertain)
  160.             {
  161.               /* if the position is uncertain calculate the new one first */
  162.               /* this will allow the same numbers to be returned by frand */
  163.               POV_SRAND (Hash3d (blockX, blockY, blockZ)) ;
  164.               Center [X] += FRAND () * Black_Hole->Uncertainty_Vector [X] ;
  165.               Center [Y] += FRAND () * Black_Hole->Uncertainty_Vector [Y] ;
  166.               Center [Z] += FRAND () * Black_Hole->Uncertainty_Vector [Z] ;
  167.             }
  168.  
  169.             Center [X] += Black_Hole->Repeat_Vector [X] * blockX ;
  170.             Center [Y] += Black_Hole->Repeat_Vector [Y] * blockY ;
  171.             Center [Z] += Black_Hole->Repeat_Vector [Z] * blockZ ;
  172.           }
  173.  
  174.           VSub (Delta, TPoint, Center) ;
  175.           VLength (Length, Delta) ;
  176.  
  177.           /* Length is the distance from the centre of the black hole */
  178.           if (Length >= Black_Hole->Radius) break ;
  179.  
  180.           if (Black_Hole->Type == 0)
  181.           {
  182.             /* now convert the length to a proportion (0 to 1) that the point
  183.                is from the edge of the black hole. a point on the perimeter
  184.                of the black hole will be 0.0 ; a point at the centre will be
  185.                1.0 ; a point exactly halfway will be 0.5, and so forth. */
  186.             Length = (Black_Hole->Radius - Length) / Black_Hole->Radius ;
  187.  
  188.             /* Strength is the magnitude of the transformation effect. firstly,
  189.                apply the Power variable to Length. this is meant to provide a
  190.                means of controlling how fast the power of the Black Hole falls
  191.                off from its centre. if Power is 2.0, then the effect is inverse
  192.                square. increasing power will cause the Black Hole to be a lot
  193.                weaker in its effect towards its perimeter. 
  194.                
  195.                finally we multiply Strength with the Black Hole's Strength
  196.                variable. if the resultant value exceeds 1.0 we clip it to 1.0.
  197.                this means a point will never be transformed by more than its
  198.                original distance from the centre. the result of this clipping
  199.                is that you will have an 'exclusion' area near the centre of
  200.                the black hole where all points whose final value exceeded or
  201.                equalled 1.0 were moved by a fixed amount. this only happens
  202.                if the Strength value of the Black Hole was greater than one. */
  203.  
  204.             Strength = pow (Length, Black_Hole->Power) * Black_Hole->Strength ;
  205.             if (Strength > 1.0) Strength = 1.0 ;
  206.             
  207.             /* if the Black Hole is inverted, it gives the impression of 'push-
  208.                ing' the pattern away from its centre. otherwise it sucks. */
  209.             VScaleEq (Delta, Black_Hole->Inverted ? -Strength : Strength) ;
  210.  
  211.             /* add the scaled Delta to the input point to end up with TPoint. */
  212.             VAddEq (TPoint, Delta) ;
  213.           }
  214.           break;
  215.           
  216.         case SPIRAL_WARP:
  217.         default:
  218.           Error("Warp type %d not yet implemented",Warp->Warp_Type);
  219.       }
  220.       Warp=Warp->Next_Warp;
  221.    }
  222.  
  223.    for (i=X; i<=Z; i++)
  224.      if (TPoint[i] > COORDINATE_LIMIT)
  225.        TPoint[i]= COORDINATE_LIMIT;
  226.      else
  227.        if (TPoint[i] < -COORDINATE_LIMIT)
  228.          TPoint[i] = -COORDINATE_LIMIT;
  229.  
  230. }
  231.  
  232.  
  233.  
  234. /*****************************************************************************
  235. *
  236. * FUNCTION
  237. *
  238. * INPUT
  239. *   
  240. * OUTPUT
  241. *   
  242. * RETURNS
  243. *   
  244. * AUTHOR
  245. *   
  246. * DESCRIPTION
  247. *
  248. * CHANGES
  249. *
  250. ******************************************************************************/
  251.  
  252. WARP *Create_Warp (Warp_Type)
  253. int Warp_Type;
  254. {
  255.  WARP *New;
  256.  TURB *TNew;
  257.  REPEAT *RNew;
  258.  SPIRAL *SNew;
  259.  TRANS *TRNew;
  260.  BLACK_HOLE *BNew;
  261.    
  262.  New = NULL;
  263.  
  264.  switch (Warp_Type)
  265.  {
  266.    case CLASSIC_TURB_WARP:
  267.    case EXTRA_TURB_WARP:
  268.      
  269.      TNew = POV_MALLOC(sizeof(TURB),"turbulence struct");
  270.  
  271.      Make_Vector(TNew->Turbulence,0.0,0.0,0.0);
  272.  
  273.      TNew->Octaves = 6;
  274.      TNew->Omega = 0.5;
  275.      TNew->Lambda = 2.0;
  276.  
  277.      New = (WARP *)TNew;
  278.  
  279.      break;
  280.      
  281.    case REPEAT_WARP:
  282.  
  283.      RNew = POV_MALLOC(sizeof(REPEAT),"repeat warp");
  284.  
  285.      RNew->Axis = -1;
  286.      RNew->Width = 0.0;
  287.  
  288.      Make_Vector(RNew->Offset,0.0,0.0,0.0);
  289.      Make_Vector(RNew->Flip,1.0,1.0,1.0);
  290.  
  291.      New = (WARP *)RNew;
  292.  
  293.      break;
  294.  
  295.    case BLACK_HOLE_WARP:
  296.      BNew = POV_MALLOC (sizeof (BLACK_HOLE), "black hole warp") ;
  297.      Make_Vector (BNew->Center, 0.0, 0.0, 0.0) ;
  298.      Make_Vector (BNew->Repeat_Vector, 0.0, 0.0, 0.0) ;
  299.      Make_Vector (BNew->Uncertainty_Vector, 0.0, 0.0, 0.0) ;
  300.      BNew->Strength = 1.0 ;
  301.      BNew->Power = 2.0 ;
  302.      BNew->Radius = 1.0 ;
  303.      BNew->Radius_Squared = 1.0 ;
  304.      BNew->Inverse_Radius = 1.0 ;
  305.      BNew->Inverted = FALSE ;
  306.      BNew->Type = 0 ;
  307.      BNew->Repeat = FALSE ;
  308.      BNew->Uncertain = FALSE ;
  309.      New = (WARP *) BNew ;
  310.      break ;
  311.  
  312.    case SPIRAL_WARP:
  313.  
  314.      SNew = POV_MALLOC(sizeof(SPIRAL),"spiral warp");
  315.  
  316.      Make_Vector(SNew->Center,0.0,0.0,0.0);
  317.  
  318.      SNew->Strength = 1.0;
  319.      SNew->Phase = 0.0;
  320.  
  321.      New = (WARP *)SNew;
  322.  
  323.      break;
  324.  
  325.    case TRANSFORM_WARP:
  326.  
  327.      TRNew = POV_MALLOC(sizeof(TRANS),"pattern transform");
  328.  
  329.      MIdentity (TRNew->Trans.matrix);
  330.      MIdentity (TRNew->Trans.inverse);
  331.  
  332.      New = (WARP *)TRNew;
  333.  
  334.      break;
  335.      
  336.    default:
  337.  
  338.      Error("Unknown Warp type %d.",Warp_Type);
  339.   }
  340.   
  341.   New->Warp_Type = Warp_Type;
  342.   New->Next_Warp = NULL;
  343.   
  344.   return(New);
  345. }
  346.  
  347.  
  348.  
  349. /*****************************************************************************
  350. *
  351. * FUNCTION
  352. *
  353. * INPUT
  354. *   
  355. * OUTPUT
  356. *   
  357. * RETURNS
  358. *   
  359. * AUTHOR
  360. *   
  361. * DESCRIPTION
  362. *
  363. * CHANGES
  364. *
  365. ******************************************************************************/
  366.  
  367. void Destroy_Warps (Warps)
  368. WARP *Warps;
  369. {
  370.  WARP *Temp1 = Warps;
  371.  WARP *Temp2;
  372.  
  373.  while (Temp1!=NULL)
  374.  {
  375.    Temp2 = Temp1->Next_Warp;
  376.  
  377.    POV_FREE(Temp1);
  378.    
  379.    Temp1 = Temp2;
  380.  }
  381. }
  382.  
  383.  
  384.  
  385. /*****************************************************************************
  386. *
  387. * FUNCTION
  388. *
  389. * INPUT
  390. *   
  391. * OUTPUT
  392. *   
  393. * RETURNS
  394. *   
  395. * AUTHOR
  396. *   
  397. * DESCRIPTION
  398. *
  399. * CHANGES
  400. *
  401. ******************************************************************************/
  402.  
  403. WARP *Copy_Warps (Old)
  404. WARP *Old;
  405. {
  406.   WARP *New;
  407.  
  408.   if (Old != NULL)
  409.   {
  410.     New=Create_Warp(Old->Warp_Type);
  411.  
  412.     switch (Old->Warp_Type)
  413.     {
  414.        case CLASSIC_TURB_WARP:
  415.        case EXTRA_TURB_WARP:
  416.          memcpy(New,Old,sizeof(TURB));
  417.          break;
  418.      
  419.        case REPEAT_WARP:
  420.          memcpy(New,Old,sizeof(REPEAT));
  421.          break;
  422.      
  423.        case BLACK_HOLE_WARP:
  424.          memcpy(New,Old,sizeof(BLACK_HOLE));
  425.          break;
  426.      
  427.        case SPIRAL_WARP:
  428.          memcpy(New,Old,sizeof(SPIRAL));
  429.          break;
  430.      
  431.        case TRANSFORM_WARP:
  432.          memcpy(New,Old,sizeof(TRANS));
  433.          break;
  434.     }
  435.     New->Next_Warp=Copy_Warps(Old->Next_Warp);
  436.   }
  437.   else
  438.   {
  439.     New=NULL;
  440.   }
  441.   return(New);
  442. }
  443.  
  444.